package com.bawei.module_moto_circle.ui.post

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import com.alibaba.android.arouter.launcher.ARouter
import com.bawei.lib_common.Router
import com.bawei.lib_common.base.state.Empty
import com.bawei.lib_common.base.state.Failed
import com.bawei.lib_common.base.state.IRetryClickListener
import com.bawei.lib_common.base.state.Loading
import com.bawei.lib_common.base.state.Success
import com.bawei.lib_common.base.state.UILoader
import com.bawei.lib_common.base.state.UIState
import com.bawei.lib_common.flow_eventbus.observe.observeEvent
import com.bawei.lib_common.flow_eventbus.post.postEvent
import com.bawei.lib_common.observeWithLifecycle
import com.bawei.lib_common.utils.LoggerUtils
import com.bawei.lib_common.utils.ToastUtils
import com.bawei.lib_common.video.VideoRecyclerViewHelper
import com.bawei.lib_net.ApiException
import com.bawei.lib_net.LoginTimeoutException
import com.bawei.lib_net.ResponseEmptyException
import com.bawei.lib_storage.mmkv.AuthMMKV
import com.bawei.module_moto_circle.R
import com.bawei.module_moto_circle.databinding.FragmentPostListBinding
import com.bawei.module_moto_circle.databinding.LayoutPostItemBinding
import com.bawei.module_moto_circle.databinding.LayoutRefreshRecyclerviewBinding
import com.bawei.module_moto_circle.helper.LikeGifAnimHelper2
import com.bawei.module_moto_circle.model.PostInfo
import com.bawei.module_moto_circle.ui.post.adapter.PostListAdapter
import com.bawei.module_moto_circle.ui.post.adapter.PostPagingAdapter
import com.bawei.module_moto_circle.ui.post.adapter.PostViewHolder
import com.bawei.module_moto_circle.ui.post.paging.PostChangeInListEvent
import com.bawei.myclub.base.mvvm.view.BaseFragment
import com.google.android.exoplayer2.util.MimeTypes
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Job

@AndroidEntryPoint
class PostListFragment : BaseFragment<PostListViewModel, FragmentPostListBinding>() {
    override val mLayoutResId: Int
        get() = R.layout.fragment_post_list
    override val mViewModel: PostListViewModel by viewModels()
    override val mPageCanBack: Boolean = false

    val helper by lazy {
        LikeGifAnimHelper2(requireActivity())
    }

    //分页参数
    private var sortType: String? = null
    private var keyword: String? = null
    private var memberId: String? = null
    private var topicId: String? = null
    private var ifFocus: Int? = null
    private lateinit var mUiLoader: UILoader
    private lateinit var mContentBinding: LayoutRefreshRecyclerviewBinding
    private var showAuthorLabel: Boolean = true
    private var mPagingJob: Job? = null
    private val postListAdapter by lazy {
        PostListAdapter(
            onLikeClick = { postItem, i ->

            },
            onLikeViewClick = { postItem, i, view ->
                if (!AuthMMKV.hasLogin()) {
                    return@PostListAdapter
                }
                //优化：开启gif动画
                if (postItem.if_like == 0) {
                    helper.setTargetView(view)
                    helper.startGif()
                }
                //优化：本地先更新UI，再发起网络请求，若失败回滚UI状态
                updateLike(i,postItem)
                //点赞
                mViewModel.giveLike(postItem.posts_id, i)

            },
            onCommentsClick = {

            },
            onShareClick = {

            },
            onCollectionViewClick = { postItem, i, view ->

            },
            onMoreActionClick = { postItem, i ->

            },
            onItemClick = { postItem, i ->
                ARouter.getInstance().build(Router.Ui.PostDetailsActivity)
                    .withString("postId", postItem.posts_id).navigation()
            },
            onUserClick = { postItem ->

            },
            onFollowViewClick = { postInfo, i, view ->
                // JLogUtil.http("onFollowViewClick called with")

                if (!AuthMMKV.hasLogin())
                    return@PostListAdapter
                // 关注
                if (postInfo.hasFollowed()) {
                    mViewModel.cancelFollow()
                } else {
                    mViewModel.followUser()
                }

            },
            showRelationState = ifFocus == 0  //是否显示关系
        )
    }

    private val mPostPagingAdapter by lazy {
        PostPagingAdapter(

            onLikeClick = { postItem, i ->

            },
            onLikeViewClick = { postItem, i, view ->
                if (!AuthMMKV.hasLogin()) {
                    return@PostPagingAdapter
                }
                //优化：开启gif动画
                if (postItem.if_like == 0) {
                    helper.setTargetView(view)
                    helper.startGif()
                }
                //优化：本地先更新UI，再发起网络请求，若失败回滚UI状态
                updateLike(i,postItem)
                //点赞
                mViewModel.giveLike(postItem.posts_id, i)

            },
            onCommentsClick = {

            },
            onShareClick = {

            },
            onCollectionViewClick = { postItem, i, view ->

            },
            onMoreActionClick = { postItem, i ->

            },
            onItemClick = { postItem, i ->
                ARouter.getInstance().build(Router.Ui.PostDetailsActivity)
                    .withString("postId", postItem.posts_id).navigation()
            },
            onUserClick = { postItem ->

            },
            onFollowViewClick = { postInfo, i, view ->
                // JLogUtil.http("onFollowViewClick called with")

                if (!AuthMMKV.hasLogin())
                    return@PostPagingAdapter
                // 关注
                if (postInfo.hasFollowed()) {
                    mViewModel.cancelFollow()
                } else {
                    mViewModel.followUser()
                }

            },
            showRelationState = ifFocus == 0  //是否显示关系
        )
    }

    private fun inFollowPage(): Boolean {
        return ifFocus != null && ifFocus == 1
    }

    //视频播放帮助类
    private val mVideoRecyclerViewHelper by lazy {
        object : VideoRecyclerViewHelper() {
            override fun getVideoUrl(position: Int): String? {
                return mPostPagingAdapter.getPostItem(position)?.image?.firstOrNull()?.url
            }

            override fun isVideo(position: Int): Boolean {
                return MimeTypes.isVideo(mPostPagingAdapter.getPostItem(position)?.image?.firstOrNull()?.contentType)
            }

            override fun getVideoContainer(viewHolder: RecyclerView.ViewHolder): FrameLayout? {
                if (viewHolder !is PostViewHolder) {
                    return null
                }
                val binding = DataBindingUtil.getBinding<LayoutPostItemBinding>(viewHolder.itemView)
                return binding?.lVideo
            }

            override fun getVideoCoverView(viewHolder: RecyclerView.ViewHolder): ImageView? {
                if (viewHolder !is PostViewHolder) {
                    return null
                }
                val binding = DataBindingUtil.getBinding<LayoutPostItemBinding>(viewHolder.itemView)
                return binding?.ivVideo
            }

            override fun getVideoIcon(viewHolder: RecyclerView.ViewHolder): View? {
                if (viewHolder !is PostViewHolder) {
                    return null
                }
                val binding = DataBindingUtil.getBinding<LayoutPostItemBinding>(viewHolder.itemView)
                return binding?.ivPlay
            }

            override fun getVideoLoadingView(viewHolder: RecyclerView.ViewHolder): View? {
                if (viewHolder !is PostViewHolder) {
                    return null
                }
                val binding = DataBindingUtil.getBinding<LayoutPostItemBinding>(viewHolder.itemView)
                return binding?.loading
            }
        }
    }

    companion object {
        private const val KEYWORD = "keyword"
        private const val SORT_TYPE = "sortType"
        private const val MEMBER_ID = "member_id"
        private const val IF_FOCUS = "IF_FOCUS"
        private const val TOPIC_ID = "topic_id"
        fun newInstance(
            ifFocus: Int? = null,
            keyword: String? = null,
            memberId: String? = null,
            sortType: String? = null,
            topicId: String? = null,
        ): PostListFragment {
            val fragment = PostListFragment()
            fragment.arguments = Bundle().apply {
                putInt(IF_FOCUS, ifFocus ?: 0)
                putString(KEYWORD, keyword)
                putString(MEMBER_ID, memberId)
                putString(TOPIC_ID, topicId)
                putString(SORT_TYPE, sortType)
            }
            return fragment
        }
    }


    override fun initView() {
        keyword = arguments?.getString(KEYWORD)
        sortType = arguments?.getString(SORT_TYPE)
        memberId = arguments?.getString(MEMBER_ID)
        ifFocus = if (arguments?.getInt(IF_FOCUS) == -1) null else arguments?.getInt(IF_FOCUS)
        topicId = arguments?.getString(TOPIC_ID)
        initUILoader()
        initAdapter()
    }

    private fun initAdapter() {
        mContentBinding.rv.adapter = mPostPagingAdapter
        mContentBinding.rv.layoutManager = LinearLayoutManager(context)
        mContentBinding.rv.setHasFixedSize(true)
        mContentBinding.rv.setItemViewCacheSize(10)
        val pool = RecycledViewPool()
        pool.setMaxRecycledViews(0, 10)
        mContentBinding.rv.setRecycledViewPool(pool)

        //视频帮助类
        mVideoRecyclerViewHelper.init(
            requireActivity(), mContentBinding.rv,
            onPlayingVideoClick = null,
            onNotPlayingVideoClick = null
        )

        mContentBinding.rv.setOnScrollChangeListener { _, _, _, _, _ ->
            val position =
                (mContentBinding.rv.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
            if (position < 3) {
                mContentBinding.ivGoToTop.visibility = View.GONE
            } else {
                mContentBinding.ivGoToTop.visibility = View.VISIBLE
            }
        }

        mContentBinding.ivGoToTop.setOnClickListener {
            mContentBinding.rv.smoothScrollToPosition(0)
        }
    }

    private fun initUILoader() {
        mContentBinding = DataBindingUtil.inflate(
            LayoutInflater.from(context),
            R.layout.layout_refresh_recyclerview,
            null,
            false
        )

        mUiLoader = object : UILoader(requireContext()) {
            override fun loadSuccessView(container: ViewGroup?): View? {
                return mContentBinding.root
            }
        }.apply { updateState(UIState.LOADING) }

        mUiLoader.onLoginClick = {

        }

        mUiLoader.setOnRetryClickListener(object : IRetryClickListener {
            override fun onRetryClick() {

            }
        })
        mBinding.layoutContent.addView(mUiLoader)
    }

    override fun initData() {
        //是否为关注页面
        if (ifFocus == 1) {
            if (!AuthMMKV.hasLogin()) {
                mUiLoader.updateState(UIState.UN_LOGIN)
            } else {
                mViewModel.checkIfHasFocus()
            }
        } else {
            getPostInfoData()
        }
    }

    //设置帖子分页参数
    fun setPagingParam(
        sortType: String?,
        keyword: String?,
        memberId: String?,
        ifFocus: Int?,
        topicId: String?
    ) {
        if (mPagingJob?.isActive == true) {
            mPagingJob!!.cancel()
        }
        this.sortType = sortType
        this.keyword = keyword
        this.memberId = memberId
        this.ifFocus = ifFocus
        this.topicId = topicId
    }

    private fun getPostInfoData() {
        //设置参数
        mViewModel.setPageParam(sortType, keyword, memberId, ifFocus, topicId)
        //网络请求数据
        //mViewModel.getPostInfo()
        mPagingJob = mViewModel.postPageEvent2.observeWithLifecycle(this) {
            mPostPagingAdapter.submitData(it)
        }
        //订阅数据
        // observerPostData()
    }

    override fun initListener() {
        //判断是否有关注的人
        mViewModel.mCheckIfHasFocus.observe(this) {
            if (it == true) {
                getPostInfoData()
            } else {
                mUiLoader.updateState(UIState.NO_FOLLOW)
            }
        }

        //点赞
        mViewModel.requestLikeEvent.observeWithLifecycle(this) {
            //点赞成功 不做处理
            //点赞失败 换回来
            //if (it == -1){
            //mPostPagingAdapter.getPostItem(it)?.let {
            //updateLike(it)
            // }
            // }

            //处理数据源
            val post = mPostPagingAdapter.getPostItem(it)!!
            if (post.if_like == 1) {
                post.if_like = 0
                if (post.like_number > 0)
                    post.like_number--
            } else {
                post.if_like = 1
                post.like_number++
            }
            //局部更新
            mPostPagingAdapter.notifyItemChanged(it, "update")
            postEvent(PostChangeInListEvent(it, post))
        }

        //关注
        //mViewModel.requestFollowEvent.observeWithLifecycle(this) {
        //处理数据源
//            val post = mPostPagingAdapter.getPostItem(it)!!
//            if (post.hasFollowed()) {
//                post.onCancelFollow()
//                ToastUtils.showLong(requireActivity(), "取消关注成功")
//            } else if (post.canFollow()) {
//                post.onFollow()
//                ToastUtils.showLong(requireActivity(), "关注成功")
//            }
//            //局部更新
//            mPostPagingAdapter.notifyItemChanged(it, "update")
//            postEvent(PostChangeInListEvent(it, post))
//        }

        mContentBinding.lRefresh.setOnRefreshListener {
            //手动刷新
            mPostPagingAdapter.refresh()
        }

        mPostPagingAdapter.loadStateFlow.observeWithLifecycle(this, Lifecycle.State.CREATED) {
            //未初始化状态
            when (it.source.refresh) {
                is LoadState.Loading -> {
                    if (mPostPagingAdapter.itemCount == 0) {
                        mUiLoader.updateState(UIState.LOADING)
                    }
                }
                is LoadState.NotLoading -> {
                    mUiLoader.updateState(UIState.SUCCESS)
                }
                is LoadState.Error -> {
                    val e = (it.refresh as LoadState.Error).error as ApiException
                    //   if (mPostPagingAdapter.itemCount == 0) {
                    //未初始化状态下出现错误
                    handleInitPageError(e)
                    //    } else {
                    // ToastUtils.showShort(context, e.message)
                    //   }
                }
            }
            mContentBinding.lRefresh.finishRefresh()
        }

        observeEvent<PostChangeInListEvent> {
            if (!it.refresh)
                mPostPagingAdapter.updatePostItem(it.position!!, it.newPost!!)
            else {
                Handler(Looper.getMainLooper()).postDelayed({
                    mPostPagingAdapter.refresh()
                }, 0)
            }
        }
    }

    private fun handleInitPageError(e: ApiException) {
        when (e) {
            is LoginTimeoutException -> {
                ToastUtils.showShort(context, e.message)
                mUiLoader.updateState(UIState.EMPTY)
            }
            is ResponseEmptyException -> {
                mUiLoader.updateState(UIState.EMPTY)
            }
            else -> {
                mUiLoader.updateState(UIState.NETWORK_ERROR)
            }
        }

    }

    private fun observerPostData() {
        mViewModel.mPostState.observeWithLifecycle(this) {
            when (it) {
                is Loading -> {
                    mUiLoader.updateState(UIState.LOADING)
                }

                is Success -> {
                    mUiLoader.updateState(UIState.SUCCESS)
                    postListAdapter.setData(mViewModel.mPostListData)
                }

                is Empty -> {
                    mUiLoader.updateState(UIState.EMPTY)
                }

                is Failed -> {
                    mUiLoader.updateState(UIState.NETWORK_ERROR)
                    LoggerUtils.d("TAG", "加载失败:" + it.message)
                }

            }
        }
    }

    private fun updateLike(position:Int,postItem: PostInfo) {
        if (postItem.if_like == 0) {
            postItem.if_like = 1
            postItem.like_number++
        } else {
            postItem.if_like = 0
            postItem.like_number--
        }
        mPostPagingAdapter.updatePostItem(position,postItem)
    }

    /**
     * 暂停播放
     */
    override fun onPause() {
        super.onPause()
        mVideoRecyclerViewHelper.pausePlayer()
    }

    /**
     * 恢复播放
     */
    override fun onResume() {
        super.onResume()
        if (isVisible)
            mVideoRecyclerViewHelper.startPlayer()
        else
            mVideoRecyclerViewHelper.hidePlayerView()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (!hidden) {
            mVideoRecyclerViewHelper.startPlayer()
        } else {
            mVideoRecyclerViewHelper.pausePlayer()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mVideoRecyclerViewHelper.releasePlayer()
    }

}